﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web.Mvc;
using System.Threading;
using CP_SchoolForChildren_v0._1.Models.DataModel;
using EntityFramework.Extensions;

namespace CP_SchoolForChildren_v0._1.Controllers.Support
{
    public class FunctionController : Controller
    {
        public SFCEntities db = new SFCEntities();
        public SFCMessage sfcMessage = new SFCMessage();
        public FunctionController()
        {
            db.Configuration.ProxyCreationEnabled = false;
        }

        public int CurrentUserID(string username)
        {
            int id = db.Users.First(us => us.UserName == username).UserID;
            return id;
        }

        public int CurrentUserRoleID()
        {
            return db.Users.First(us => us.UserName == User.Identity.Name).RoleID;
        }

        
        public string RankAllSchool()
        {
            try
            {
                var currentrank = db.SystemRatings.ToList();
                foreach(var tmr in currentrank)
                {
                    db.SystemRatings.Remove(tmr);
                }
                db.SaveChanges();

                var school = from sc in db.Schools
                             select new {
                                 sc.SchoolID,
                                 sc.Area,
                                 sc.NumberOfChildren,
                                 sc.NumberOfTeacher
                             };
                var standard = db.ReferenceStandards.ToList();                
                foreach (var tmp in school)
                {
                    Thread.Sleep(500);
                    var rankingService = from sc in db.Schools
                                          from sv in db.Services
                                          from ss in db.SchoolServices
                                          where ss.SchoolID == sc.SchoolID
                                          where ss.ServiceID == sv.ServiceID
                                          where sc.SchoolID == tmp.SchoolID
                                          group sv by sc.SchoolID into rs
                                          select new
                                          {
                                              severicepoint = rs.Sum(d => d.Weight)
                                          };

                    double servicepoint = 0;
                    if (rankingService.ToList().Any())
                    {
                       servicepoint = rankingService.ToList().First().severicepoint;
                        if (servicepoint > 3)
                            servicepoint = 3;
                    }

                    double areastandard = standard.Where(s => s.ReferenceStandardID == 2).ToList().First().Standard;

                    double areapoint = tmp.Area / tmp.NumberOfChildren / areastandard;
                    if (areapoint > 1)
                        areapoint = 1;

                    double sisostandard = standard.Where(s => s.ReferenceStandardID == 1).ToList().First().Standard;

                    double sisopoint = (double)tmp.NumberOfTeacher / tmp.NumberOfChildren / sisostandard;
                    if (sisopoint > 1)
                        sisopoint = 1;


                    var systemrating = new SystemRating();

                    systemrating.SchoolID = tmp.SchoolID;
                    systemrating.SystemRate = servicepoint + areapoint + sisopoint;

                    db.Entry(systemrating).State = System.Data.EntityState.Added;

                }
                db.SaveChanges();
                return "OK";
            }catch (Exception ex)
            {
                return "Error" + ex.ToString();
            }               
        }

        public string RankSchool(int schoolID)
        {
            try
            {

                var school = from sc in db.Schools
                             where sc.SchoolID == schoolID
                             select new
                                        {
                                            sc.SchoolID,
                                            sc.Area,
                                            sc.NumberOfChildren,
                                            sc.NumberOfTeacher
                                        };
                var standard = db.ReferenceStandards.ToList();
                var tmp = school.First();
                    Thread.Sleep(500);
                    var rankingService = from sc in db.Schools
                                         from sv in db.Services
                                         from ss in db.SchoolServices
                                         where ss.SchoolID == sc.SchoolID
                                         where ss.ServiceID == sv.ServiceID
                                         where sc.SchoolID == tmp.SchoolID
                                         group sv by sc.SchoolID into rs
                                         select new
                                         {
                                             severicepoint = rs.Sum(d => d.Weight)
                                         };

                    double servicepoint = 0;
                    if (rankingService.ToList().Any())
                    {
                        servicepoint = rankingService.ToList().First().severicepoint;
                        if (servicepoint > 3)
                            servicepoint = 3;
                    }

                    double areastandard = standard.Where(s => s.ReferenceStandardID == 2).ToList().First().Standard;

                    double areapoint = tmp.Area / tmp.NumberOfChildren / areastandard;
                    if (areapoint > 1)
                        areapoint = 1;

                    double sisostandard = standard.Where(s => s.ReferenceStandardID == 1).ToList().First().Standard;

                    double sisopoint = (double)tmp.NumberOfTeacher / tmp.NumberOfChildren / sisostandard;
                    if (sisopoint > 1)
                        sisopoint = 1;


                    var systemrating = new SystemRating();

                    systemrating.SchoolID = tmp.SchoolID;
                    systemrating.SystemRate = servicepoint + areapoint + sisopoint;

                    db.Entry(systemrating).State = System.Data.EntityState.Added;

                db.SaveChanges();
                return "OK";
            }
            catch (Exception ex)
            {
                return "Error" + ex.ToString();
            }
        }

        public string FirstImage(string articleContent)
        {
           String regex = "http://(\\S+?)\\.(jpg|png|gif|jpeg|bmp)";
           return Regex.Match(articleContent,regex).Value;
        }
        public string StripHTML(string source)
        {
            try
            {
                string result; ;

                // Remove HTML Development formatting
                // Replace line breaks with space
                // because browsers inserts space
                result = source.Replace("\r", " ");
                // Replace line breaks with space
                // because browsers inserts space
                result = result.Replace("\n", " ");
                // Remove step-formatting
                result = result.Replace("\t", string.Empty);
                // Remove repeating spaces because browsers ignore them
                result = System.Text.RegularExpressions.Regex.Replace(result,
                                                                      @"( )+", " ");

                // Remove the header (prepare first by clearing attributes)
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*head([^>])*>", "<head>",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"(<( )*(/)( )*head( )*>)", "</head>",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(<head>).*(</head>)", string.Empty,
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // remove all scripts (prepare first by clearing attributes)
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*script([^>])*>", "<script>",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"(<( )*(/)( )*script( )*>)", "</script>",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                //result = System.Text.RegularExpressions.Regex.Replace(result,
                //         @"(<script>)([^(<script>\.</script>)])*(</script>)",
                //         string.Empty,
                //         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"(<script>).*(</script>)", string.Empty,
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // remove all styles (prepare first by clearing attributes)
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*style([^>])*>", "<style>",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"(<( )*(/)( )*style( )*>)", "</style>",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(<style>).*(</style>)", string.Empty,
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // insert tabs in spaces of <td> tags
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*td([^>])*>", "\t",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // insert line breaks in places of <BR> and <LI> tags
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*br( )*>", "\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*li( )*>", "\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // insert line paragraphs (double line breaks) in place
                // if <P>, <DIV> and <TR> tags
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*div([^>])*>", "\r\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*tr([^>])*>", "\r\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*p([^>])*>", "\r\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // Remove remaining tags like <a>, links, images,
                // comments etc - anything that's enclosed inside < >
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<[^>]*>", string.Empty,
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                //// replace special characters:
                //result = System.Text.RegularExpressions.Regex.Replace(result,
                //         @" ", " ",
                //         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                //result = System.Text.RegularExpressions.Regex.Replace(result,
                //         @"&bull;", " * ",
                //         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                //result = System.Text.RegularExpressions.Regex.Replace(result,
                //         @"&lsaquo;", "<",
                //         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                //result = System.Text.RegularExpressions.Regex.Replace(result,
                //         @"&rsaquo;", ">",
                //         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                //result = System.Text.RegularExpressions.Regex.Replace(result,
                //         @"&trade;", "(tm)",
                //         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                //result = System.Text.RegularExpressions.Regex.Replace(result,
                //         @"&frasl;", "/",
                //         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                //result = System.Text.RegularExpressions.Regex.Replace(result,
                //         @"&lt;", "<",
                //         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                //result = System.Text.RegularExpressions.Regex.Replace(result,
                //         @"&gt;", ">",
                //         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                //result = System.Text.RegularExpressions.Regex.Replace(result,
                //         @"&copy;", "(c)",
                //         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                //result = System.Text.RegularExpressions.Regex.Replace(result,
                //         @"&reg;", "(r)",
                //         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                //// Remove all others. More can be added, see
                //// http://hotwired.lycos.com/webmonkey/reference/special_characters/
                //result = System.Text.RegularExpressions.Regex.Replace(result,
                //         @"&(.{2,6});", string.Empty,
                //         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // for testing
                //System.Text.RegularExpressions.Regex.Replace(result,
                //       this.txtRegex.Text,string.Empty,
                //       System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // make line breaking consistent
                result = result.Replace("\n", "\r");

                // Remove extra line breaks and tabs:
                // replace over 2 breaks with 2 and over 4 tabs with 4.
                // Prepare first to remove any whitespaces in between
                // the escaped characters and remove redundant tabs in between line breaks
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(\r)( )+(\r)", "\r\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(\t)( )+(\t)", "\t\t",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(\t)( )+(\r)", "\t\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(\r)( )+(\t)", "\r\t",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                // Remove redundant tabs
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(\r)(\t)+(\r)", "\r\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                // Remove multiple tabs following a line break with just one tab
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(\r)(\t)+", "\r\t",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                // Initial replacement target string for line breaks
                string breaks = "\r\r\r";
                // Initial replacement target string for tabs
                string tabs = "\t\t\t\t\t";
                for (int index = 0; index < result.Length; index++)
                {
                    result = result.Replace(breaks, "\r\r");
                    result = result.Replace(tabs, "\t\t\t\t");
                    breaks = breaks + "\r";
                    tabs = tabs + "\t";
                }

                // That's it.
                return result;
            }
            catch
            {
                return source;
            }
        }

        public List<int> ListService()
        {
            //int[] list;
            var record = (from svr in db.Services
                         select svr.ServiceID);
            return record.ToList();
        }

        [HttpGet]
        public JsonResult GetCityOptionsByGet()
        {
            try
            {
                var record = db.Cities.Where(c => c.Districts.Count > 0).Select(c => new { DisplayText = c.CityName, Value = c.CityID });
                return Json(new { Result = "OK", Options = record }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return Json(new { Result = "ERROR", Message = sfcMessage.ServerError }, JsonRequestBehavior.AllowGet);
            }
        }

        [HttpGet]
        public JsonResult GetSchoolTypeOptionsByGet()
        {
            try
            {
                var record = db.SchoolTypes.Where(st => st.TypeID != 1).Select(st => new { DisplayText = st.TypeName, Value = st.TypeID });
                return Json(new { Result = "OK", Options = record }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return Json(new { Result = "ERROR", Message = sfcMessage.ServerError }, JsonRequestBehavior.AllowGet);
            }
        }

        [HttpGet]
        public JsonResult GetServiceCheckListByGet()
        {
            try
            {
                var record = db.Services.Where(s => s.ServiceID != 1).Select(st => new { DisplayText = st.ServiceName, Value = st.ServiceID });
                return Json(new { Result = "OK", Options = record }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return Json(new { Result = "ERROR", Message = sfcMessage.ServerError }, JsonRequestBehavior.AllowGet);
            }
        }

        [HttpGet]
        public JsonResult GetDistrictOptions(int cityId)
        {
            try
            {
                var record = db.Districts.Where(d => d.CityID == cityId).Where(d => d.DistrictID != 1)
                    .Select(d => new { DisplayText = d.DistrictName, Value = d.DistrictID });
                return Json(new { Result = "OK", Options = record }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return Json(new { Result = "ERROR", Message = ex.Message }, JsonRequestBehavior.AllowGet);
            }
        }

        [HttpGet]
        public JsonResult GetServiceCheckListByGetForIndex()
        {
            try
            {
                List<int> ServiceList = new List<int>()
                                            {
                                                1,2,3,4,5,6,7
                                            };
                var record = db.Services.Where(s => s.ServiceID != 1).Where(s => ServiceList.Contains(s.ServiceID)).Select(st => new { DisplayText = st.ServiceName, Value = st.ServiceID });
                return Json(new { Result = "OK", Options = record }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return Json(new { Result = "ERROR", Message = sfcMessage.ServerError }, JsonRequestBehavior.AllowGet);
            }
        }
    }
}
